package com.miaosha.service.impl;

import com.miaosha.dao.OrderDOMapper;
import com.miaosha.dao.SequenceDOMapper;
import com.miaosha.dataobject.OrderDO;
import com.miaosha.dataobject.SequenceDO;
import com.miaosha.error.EnumError;
import com.miaosha.error.ErrorException;
import com.miaosha.model.OrderModel;
import com.miaosha.model.ProductModel;
import com.miaosha.model.UserInformationModel;
import com.miaosha.service.OrderService;
import com.miaosha.service.ProductService;
import com.miaosha.service.UserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ProductService productService;

    @Autowired
    private UserService userService;

    @Autowired
    private OrderDOMapper orderDOMapper;

    @Autowired
    private SequenceDOMapper sequenceDOMapper;

    @Override
    @Transactional
    public OrderModel createOrder(Integer userId, Integer productId, Integer promoId, Integer amount) throws ErrorException {
        // 1.校验下单状态
        ProductModel productModel = productService.getProductDetailById(productId);
        if (productModel == null){
            throw new ErrorException(EnumError.PRODUCT_NOT_EXIST);
        }
        UserInformationModel userInformationModel = userService.getUserById(userId);
        if (userInformationModel == null){
            throw new ErrorException(EnumError.USER_NOT_EXIST);
        }
        if (amount <= 0 && amount > 99){
            throw new ErrorException(EnumError.PARAMETER_VALIDATION_ERROR, "购买数量不正确");
        }
        if (promoId != null){
            // 判断活动是否存在这个适用商品
            if (promoId.intValue() != productModel.getPromoModel().getId().intValue()){
                throw  new ErrorException(EnumError.PARAMETER_VALIDATION_ERROR, "活动信息错误");
            } else if (productModel.getPromoModel().getStatus() != 2){
                throw  new ErrorException(EnumError.PARAMETER_VALIDATION_ERROR, "活动未开始");
            }
        }

        // 2.落单减库存  支付减库存
        boolean result = productService.decreaseStock(productId, amount);
        if (!result){
            throw new ErrorException(EnumError.STOCK_NOT_ENOUGHT);
        }

        // 3.订单入库
        OrderModel orderModel = new OrderModel();
        orderModel.setUserId(userId);
        orderModel.setProductId(productId);
        orderModel.setAmount(amount);
        if (promoId != null) {
            orderModel.setPromoId(promoId);
            orderModel.setProductPrice(productModel.getPromoModel().getPromoProductPrice());
        } else {
            orderModel.setProductPrice(productModel.getPrice());
        }
        orderModel.setOrderPrice(orderModel.getProductPrice().multiply(new BigDecimal(amount)));

        // 生成交易流水号  订单号
        orderModel.setId(generateOrderNo());
        OrderDO orderDO = convertOrderDOFromOrderModel(orderModel);
        orderDOMapper.insertSelective(orderDO);

        // 4.加上商品销量
        productService.increaseSales(productId, amount);

        // 5.返回前端
        return orderModel;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    String generateOrderNo(){
        // 订单号16位
        StringBuilder stringBuilder = new StringBuilder();
        // 前8位年月日
        LocalDateTime date = LocalDateTime.now();
        String nowDate = date.format(DateTimeFormatter.ISO_DATE).replace("-", "");
        stringBuilder.append(nowDate);

        // 6位自增序列
        SequenceDO sequenceDO = sequenceDOMapper.getSequenceByName("order_info");
        Integer currentValue = sequenceDO.getCurrentValue();
        sequenceDO.setCurrentValue(sequenceDO.getCurrentValue() + sequenceDO.getStep());
        sequenceDOMapper.updateByPrimaryKeySelective(sequenceDO);
        stringBuilder.append(String.format("%06d",currentValue));

        // 2位分库表位
        stringBuilder.append("00");
        return stringBuilder.toString();
    }


    public static void main(String[] args){
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(String.format("%06d", 10));
        System.out.print(stringBuilder.toString());
    }


    private OrderDO convertOrderDOFromOrderModel(OrderModel orderModel){
        if (orderModel == null) return null;
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(orderModel, orderDO);
        orderDO.setProductPrice(orderModel.getProductPrice().doubleValue());
        orderDO.setOrderPrice(orderModel.getOrderPrice().doubleValue());
        return orderDO;
    }
}
